/**
 * xEditor富文本编辑器
 * author: imlzw
 * url: adai.imlzw.cn
 * 配置参数：
 *
 */

layui.define(['layer', 'jquery'], function (exports) {
        var $ = window.$ = layui.jquery;

        let resources = [];

        let XEditor = function () {
            this.v = '1.0.0';
            this.renderObj;
            this.renderIns = {};
        }

        let toolbars = [
            [
                'undo', //撤销
                'redo', //重做
                'bold', //加粗
                'indent', //首行缩进
                // 'snapscreen', //截图
                'italic', //斜体
                'underline', //下划线
                'strikethrough', //删除线
                'subscript', //下标
                'fontborder', //字符边框
                'superscript', //上标
                'formatmatch', //格式刷
                'blockquote', //引用
                'pasteplain', //纯文本粘贴模式
                'selectall', //全选
                'print', //打印
                'preview', //预览
                'horizontal', //分隔线
                'removeformat', //清除格式
                'time', //时间
                'date', //日期
                'unlink', //取消链接
                // 'insertrow', //前插入行
                // 'insertcol', //前插入列
                // 'mergeright', //右合并单元格
                // 'mergedown', //下合并单元格
                // 'deleterow', //删除行
                // 'deletecol', //删除列
                // 'splittorows', //拆分成行
                // 'splittocols', //拆分成列
                // 'splittocells', //完全拆分单元格
                // 'deletecaption', //删除表格标题
                // 'inserttitle', //插入标题
                // 'mergecells', //合并多个单元格
                // 'deletetable', //删除表格
                'cleardoc', //清空文档
                // 'insertparagraphbeforetable', //"表格前插入行"
                'insertcode', //代码语言
                'fontfamily', //字体
                'fontsize', //字号
                'paragraph', //段落格式
                // 'simpleupload', //单图上传
                'insertimage', //多图上传
                // 'edittable', //表格属性
                // 'edittd', //单元格属性
                'link', //超链接
                // 'emotion', //表情
                'spechars', //特殊字符
                'searchreplace', //查询替换
                'map', //Baidu地图
                // 'gmap', //Google地图
                'insertvideo', //视频
                'justifyleft', //居左对齐
                'justifyright', //居右对齐
                'justifycenter', //居中对齐
                'justifyjustify', //两端对齐
                'forecolor', //字体颜色
                'backcolor', //背景色
                'insertorderedlist', //有序列表
                'insertunorderedlist', //无序列表
                // 'fullscreen', //全屏
                'directionalityltr', //从左向右输入
                'directionalityrtl', //从右向左输入
                'rowspacingtop', //段前距
                'rowspacingbottom', //段后距
                'pagebreak', //分页
                'insertframe', //插入Iframe
                'imagenone', //默认
                'imageleft', //左浮动
                'imageright', //右浮动
                'attachment', //附件
                'imagecenter', //居中
                'wordimage', //图片转存
                'lineheight', //行间距
                // 'edittip ', //编辑提示
                // 'customstyle', //自定义标题
                // 'autotypeset', //自动排版
                // 'webapp', //百度应用
                // 'touppercase', //字母大写
                // 'tolowercase', //字母小写
                'background', //背景
                'template', //模板
                'scrawl', //涂鸦
                // 'music', //音乐
                'inserttable', //插入表格
                // 'drafts', // 从草稿箱加载
                // 'charts', // 图表
                'anchor', //锚点
                'help', //帮助
                'source', //源代码
            ]
        ]

        /**
         * 加载js文件
         <script type="text/javascript" charset="utf-8" src="neditor.config.js"></script>
         <script type="text/javascript" charset="utf-8" src="neditor.all.min.js"> </script>
         <script type="text/javascript" charset="utf-8" src="neditor.service.js"></script>
         <!--建议手动加在语言，避免在ie下有时因为加载语言失败导致编辑器加载失败-->
         <!--这里加载的语言文件会覆盖你在配置项目里添加的语言类型，比如你在配置项目里配置的是英文，这里加载的中文，那最后就是中文-->
         <script type="text/javascript" charset="utf-8" src="i18n/zh-cn/zh-cn.js"></script>

         <script type="text/javascript" src="third-party/browser-md5-file.min.js"></script>
         <script type="text/javascript" src="third-party/jquery-1.10.2.min.js"></script>
         */
        XEditor.prototype.load = function (config, callback) {
            config.base = config.base ? config.base.endsWith("/") ? config.base : config.base + "/" : '/';
            let _this = this;
            _this.loadJS(config.base + "neditor/neditor.config.js", function () {
                _this.loadJS(config.base + "neditor/neditor.all.js", function () {
                    _this.loadJS(config.base + "neditor/neditor.service.js", function () {
                        _this.loadJS(config.base + "neditor/i18n/zh-cn/zh-cn.js", function () {
                            _this.loadJS(config.base + "neditor/third-party/browser-md5-file.min.js", function () {
                                _this.loadCss(config.base + "xEditor.css", function () {
                                    callback && callback();
                                });
                            });
                        });
                    });
                });
            });
        }

        /**
         * 配置图片上传
         */
        function configImageUpload() {
            /**
             * 图片上传service
             * @param {Object} context UploadImage对象 图片上传上下文
             * @param {Object} editor  编辑器对象
             * @returns imageUploadService 对象
             */
            window.UEDITOR_CONFIG['imageUploadService'] = function (context, editor) {
                return {
                    /**
                     * 触发fileQueued事件时执行
                     * 当文件被加入队列以后触发，用来设置上传相关的数据 (比如: url和自定义参数)
                     * @param {Object} file 当前选择的文件对象
                     */
                    setUploadData: function (file) {
                        return file;
                    },
                    /**
                     * 触发uploadBeforeSend事件时执行
                     * 在文件上传之前触发，用来添加附带参数
                     * @param {Object} object 当前上传对象
                     * @param {Object} data 默认的上传参数，可以扩展此对象来控制上传参数
                     * @param {Object} headers 可以扩展此对象来控制上传头部
                     * @returns 上传参数对象
                     */
                    setFormData: function (object, data, headers) {
                        return data;
                    },
                    /**
                     * 触发startUpload事件时执行
                     * 当开始上传流程时触发，用来设置Uploader配置项
                     * @param {Object} uploader
                     * @returns uploader
                     */
                    setUploaderOptions: function (uploader) {
                        return uploader;
                    },
                    /**
                     * 触发uploadSuccess事件时执行
                     * 当文件上传成功时触发，可以在这里修改上传接口返回的response对象
                     * @param {Object} res 上传接口返回的response
                     * @returns {Boolean} 上传接口返回的response成功状态条件 (比如: res.code == 200)
                     */
                    getResponseSuccess: function (res) {
                        return res.success;
                    },
                    /* 指定上传接口返回的response中图片路径的字段，默认为 url
                     * 如果图片路径字段不是res的属性，可以写成 对象.属性 的方式，例如：data.url
                     * */
                    imageSrcField: 'data.file_url'
                }
            };

            /**
             * 涂鸦上传service
             * @param {Object} context scrawlObj对象
             * @param {Object} editor  编辑器对象
             * @returns scrawlUploadService 对象
             */
            window.UEDITOR_CONFIG['scrawlUploadService'] = function(context, editor) {
                return scrawlUploadService = {
                    /**
                     * 点击涂鸦模态框确认按钮时触发
                     * 上传涂鸦图片
                     * @param {Object} file 涂鸦canvas生成的图片
                     * @param {Object} base64 涂鸦canvas生成的base64
                     * @param {Function} success 上传成功回调函数,回传上传成功的response对象
                     * @param {Function} fail 上传失败回调函数,回传上传失败的response对象
                     */

                    /**
                     * 上传成功的response对象必须为以下两个属性赋值
                     *
                     * 上传接口返回的response成功状态条件 {Boolean} (比如: res.code == 200)
                     * res.responseSuccess = res.code == 200;
                     *
                     * 指定上传接口返回的response中涂鸦图片路径的字段，默认为 url
                     * res.videoSrcField = 'url';
                     */
                    uploadScraw: function(file, base64, success, fail) {

                        /* 模拟上传操作 */
                        var formData = new FormData();
                        formData.append('file', file, file.name);

                        $.ajax({
                            url: editor.getActionUrl(editor.getOpt('scrawlActionName')),
                            type: 'POST',
                            //ajax2.0可以不用设置请求头，但是jq帮我们自动设置了，这样的话需要我们自己取消掉
                            contentType: false,
                            //取消帮我们格式化数据，是什么就是什么
                            processData: false,
                            data: formData
                        }).done(function(res) {
                            console.log('res', res);

                            /* 上传接口返回的response成功状态条件 (比如: res.code == 200) */
                            res.responseSuccess = res.success;

                            /* 指定上传接口返回的response中涂鸦图片路径的字段，默认为 url
                             * 如果涂鸦图片路径字段不是res的属性，可以写成 对象.属性 的方式，例如：data.url
                             */
                            res.scrawlSrcField = 'data.file_url';

                            /* 上传成功 */
                            success.call(context, res);
                        }).fail(function(err) {
                            /* 上传失败 */
                            fail.call(context, err);
                        });
                    }
                }
            }
        }

        function configActionUrl(config) {
            UE.Editor.prototype._bkGetActionUrl = UE.Editor.prototype.getActionUrl;
            UE.Editor.prototype.getActionUrl = function (action) {
                console.log(action, 'action', config);
                /* 按config中的xxxActionName返回对应的接口地址 */
                if (action == 'uploadimage' || action == 'uploadscrawl') {
                    return config.imageUploadUrl;
                } else if (action == 'uploadvideo') {
                    return config.videoUploadUrl;
                } else {
                    return this._bkGetActionUrl.call(this, action);
                }
            }
        }

        /**
         * 渲染组件
         * @param config
         */
        XEditor.prototype.render = function (config) {
            config.base = layui.cache.modules.xEditor.replace("xEditor.js", "") || '';
            let _this = this;
            _this.load(config, function () {
                configActionUrl(config);
                configImageUpload();
                //实例化编辑器
                //建议使用工厂方法getEditor创建和引用编辑器实例，如果在某个闭包下引用该编辑器，直接调用UE.getEditor('editor')就能拿到相关的实例
                let opt = {...config, UEDITOR_HOME_URL: config.base + "neditor/", toolbars: toolbars};
                opt = {
                    ...opt,
                    imageActionName: "uploadimage",
                    scrawlActionName: "uploadscrawl",
                    videoActionName: "uploadvideo",
                    fileActionName: "uploadfile",
                    imageFieldName: "file", // 提交的图片表单名称
                }
                var ue = UE.getEditor(config.id, opt);
                _this.renderIns[config.id] = ue;
                return ue;
            });
        }


        /**
         * 动态加载js文件
         * @param url
         * @param callback
         */
        XEditor.prototype.loadJS = function (url, callback) {
            if (this.isLoaded(url)) {
                callback && callback();
                return;
            }
            var script = document.createElement('script'),
                fn = callback || function () {
                };
            script.type = 'text/javascript';
            //IE
            if (script.readyState) {
                script.onreadystatechange = function () {
                    if (script.readyState == 'loaded' || script.readyState == 'complete') {
                        script.onreadystatechange = null;
                        fn();
                    }
                };
            } else {
                //其他浏览器
                script.onload = function () {
                    fn();
                };
            }
            script.src = url;
            document.getElementsByTagName('head')[0].appendChild(script);
        }

        /**
         * 加载css文件
         * @param url
         */
        XEditor.prototype.loadCss = function (url, callback) {
            if (!url || url.length === 0) {
                throw new Error('argument "url" is required !');
            }
            if (this.isLoaded(url)) {
                callback && callback();
                return;
            }
            var head = document.getElementsByTagName('head')[0];
            var link = document.createElement('link');
            link.href = url;
            link.rel = 'stylesheet';
            link.type = 'text/css';
            link.onload = function () {
                resources.push(url);
                if (callback != null) {
                    callback();
                }
            };
            head.appendChild(link);
        }

        /**
         * 判断是否加载过资源了
         * @param url
         * @returns {boolean}
         */
        XEditor.prototype.isLoaded = function (url) {
            if (url) {
                for (let urlResource of resources) {
                    if (url == urlResource) {
                        return true;
                    }

                }
            }
            return false;
        }

        exports('xEditor', new XEditor());
    }
);